package service

import (
	"encoding/json"
	"canliancontract/log"
	"canliancontract/module"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/protos/peer"
	"canliancontract/common"
	"fmt"
)

/**
 * 信息上链
**/
func Register(stub shim.ChaincodeStubInterface, paramList []interface{}) peer.Response {
	// 	获得chan 返回的值
	returnInfo := module.ReturnInfo{}

	var city_disability_num map[string]int
	city_disability_num = make(map[string]int)

	var city_rehabilitation_num map[string]int
	city_rehabilitation_num = make(map[string]int)

	var city_subsidy_num map[string]int
	city_subsidy_num = make(map[string]int)

	var num1,num2,num3 int
	num1 = 0
	num2 = 0
	num3 = 0

	if paramList == nil {
		log.Logger.Error("+++++++++++上链数据为空+++++++++++++++++++")
		returnInfo.Success = false
		return shim.Error("上链数据为空")
	}

	errNum := 0

	for i, v := range paramList {
		log.Logger.Info("Register --- send :" + strconv.Itoa(i))
		var record map[string]interface{}
		b, err := json.Marshal(v)
		if err != nil {
			return shim.Error("***********" + err.Error())
		}
		json.Unmarshal(b, &record)

		_,ok := record["city"]
		if !ok{
			log.Logger.Error("no city")
			return shim.Error("!!!!!!!!city未传!!!!!!!!!")
		}

		code := int(record["type"].(float64))
		switch code {
		case 0:
			city_disability_num[record["city"].(string)]++
			num1++

		case 1:
			city_rehabilitation_num[record["city"].(string)]++
			num2++

		case 2:
			city_subsidy_num[record["city"].(string)]++
			num3++

		default:


		}
		//city_disability_num.CityDisabilityNum[record["city"].(string)] = 1
		_,ok = record["hash"]
		if !ok{
			log.Logger.Error("no hash")
			return shim.Error("!!!!!!!!hash未传!!!!!!!!!")
		}


		tChan := toRegister(stub, record)


		if tChan.Status == false {
			errNum++
		}

		returnInfo.List = append(returnInfo.List, tChan)
	}
	if errNum > 0 {
		log.Logger.Error("+++++++++++++++++++++LENGTH+++++++++++++++++++++++", len(returnInfo.List))
		returnInfo.Success = false
		return shim.Error("上链失败")
	} else {
		returnInfo.Success = true

		recordNumber(stub, len(paramList), num1, num2, num3, city_disability_num, city_rehabilitation_num, city_subsidy_num)
		// 记录tx count number
		recordTxNumber(stub, len(paramList))

		//cityDisabilityNum(stub, city_disability_num)

		//cityRehabilitationNum(stub, city_rehabilitation_num)

		//citySubsidyNum(stub, city_subsidy_num)


		//recordRehabilitationTxNumber(stub, num2)

		//recordSubsidyTxNumber(stub, num3)

		jsonReturn, _ := json.Marshal(returnInfo)
		return shim.Success(jsonReturn)
	}
}


func recordNumber(stub shim.ChaincodeStubInterface,allTx  int ,disabilityNum int ,rehabilitationNum int,subsidyNum int,city_disability_num map[string]int,city_rehabilitation_num map[string]int,city_subsidy_num map[string]int) {
	log.Logger.Info("==============================统计数据=============================================")
	countByts, err := stub.GetState(common.COUNT_ALL_NUMBER)
	if err != nil {
		var numCount module.NumCount
		numCount.AllTXNum = allTx
		numCount.DisabilityNum = disabilityNum
		numCount.RehabilitationNum = rehabilitationNum
		numCount.SubsidyNum = subsidyNum
		numCount.CityDisabilityNum = make(map[string]int)
		for i, v := range city_disability_num {
			numCount.CityDisabilityNum[i] = v
		}
		numCount.CityRehabilitationNum = make(map[string]int)
		for i, v := range city_rehabilitation_num {
			numCount.CityRehabilitationNum[i] = v
		}
		numCount.CitySubsidyNum = make(map[string]int)
		for i, v := range city_subsidy_num {
			numCount.CitySubsidyNum[i] = v
		}
		txBytes, _ := json.Marshal(numCount)
		fmt.Println(numCount)
		_ = stub.PutState(common.COUNT_ALL_NUMBER, txBytes)
	} else {
		numCount := module.NumCount{AllTXNum:0,DisabilityNum:0,RehabilitationNum:0,SubsidyNum:0,CityDisabilityNum:nil ,CityRehabilitationNum:nil ,CitySubsidyNum:nil}
		err = json.Unmarshal(countByts, &numCount)
		if err != nil {
			var numCount module.NumCount
			numCount.AllTXNum = allTx
			numCount.DisabilityNum = disabilityNum
			numCount.RehabilitationNum = rehabilitationNum
			numCount.SubsidyNum = subsidyNum
			numCount.CityDisabilityNum = make(map[string]int)
			for i, v := range city_disability_num {
				numCount.CityDisabilityNum[i] = v
			}
			numCount.CityRehabilitationNum = make(map[string]int)
			for i, v := range city_rehabilitation_num {
				numCount.CityRehabilitationNum[i] = v
			}
			numCount.CitySubsidyNum = make(map[string]int)
			for i, v := range city_subsidy_num {
				numCount.CitySubsidyNum[i] = v
			}
			txBytes, _ := json.Marshal(numCount)
			fmt.Println(numCount)
			_ = stub.PutState(common.COUNT_ALL_NUMBER, txBytes)
		} else {
			numCount.AllTXNum = allTx + numCount.AllTXNum
			numCount.SubsidyNum = numCount.SubsidyNum + subsidyNum
			numCount.DisabilityNum = numCount.DisabilityNum + disabilityNum
			numCount.RehabilitationNum = numCount.RehabilitationNum + rehabilitationNum

			for i , v := range city_subsidy_num {
				numCount.CitySubsidyNum[i] = numCount.CitySubsidyNum[i] + v
			}

			for i, v := range city_disability_num {
				numCount.CityDisabilityNum[i] = numCount.CityDisabilityNum[i] + v
			}

			for i, v := range city_rehabilitation_num {
				numCount.CityRehabilitationNum[i] = numCount.CityRehabilitationNum[i] + v
			}
			txBytes, _ := json.Marshal(numCount)
			fmt.Println(numCount)
			_ = stub.PutState(common.COUNT_ALL_NUMBER, txBytes)
		}
	}
}

/**
 * 记录当前块高度
 */
func recordTxNumber(stub shim.ChaincodeStubInterface, num int) {
	fmt.Println("========================记录当前块高度========================")
	// 记录tx count number
	countByts, err := stub.GetState(common.TX_COUNT + common.ULINE + common.TX_NUMBER)
	if err != nil {
		var txCount module.TxCount
		txCount.Count = uint64(num)
		txBytes, _ := json.Marshal(txCount)
		fmt.Println(txCount)
		_ = stub.PutState(common.TX_COUNT+common.ULINE+common.TX_NUMBER, txBytes)
	} else {
		txCount := module.TxCount{Count: 0}
		err = json.Unmarshal(countByts, &txCount)
		if err != nil {
			var txInfo module.TxCount
			txInfo.Count = uint64(num)
			txInfoBytes, _ := json.Marshal(txInfo)
			fmt.Println(txInfo)
			_ = stub.PutState(common.TX_COUNT+common.ULINE+common.TX_NUMBER, txInfoBytes)
		} else {
			txCount.Count = txCount.Count + uint64(num)
			txBytes, _ := json.Marshal(txCount)
			fmt.Println(txCount)
			_ = stub.PutState(common.TX_COUNT+common.ULINE+common.TX_NUMBER, txBytes)
		}
	}
}


// 统计对应城市的残疾人数据
/*func cityDisabilityNum(stub shim.ChaincodeStubInterface, param map[string]int) {
	fmt.Println("========================统计对应城市的残疾人数据========================")
	countByts, err := stub.GetState(common.CITY_DISABILITY_NUM)
	if err != nil {
		var city_disability_num module.CityDisabilityNum
		city_disability_num.CityDisabilityNum = make(map[string]int)
		for i, v := range param {
			city_disability_num.CityDisabilityNum[i] = v
		}
		cityDisabilityNumBytes, _ := json.Marshal(city_disability_num)
		fmt.Println(city_disability_num)
		_ = stub.PutState(common.CITY_DISABILITY_NUM, cityDisabilityNumBytes)
	} else {
		city_disability_num := module.CityDisabilityNum{CityDisabilityNum: make(map[string]int)}
		err = json.Unmarshal(countByts, &city_disability_num)
		if err != nil {
			var city_disability_num module.CityDisabilityNum
			city_disability_num.CityDisabilityNum = make(map[string]int)
			for i, v := range param {
				city_disability_num.CityDisabilityNum[i] = v
			}
			cityDisabilityNumBytes, _ := json.Marshal(city_disability_num)
			fmt.Println(city_disability_num)
			_ = stub.PutState(common.CITY_DISABILITY_NUM, cityDisabilityNumBytes)
		} else {
			for i, v := range param {
				city_disability_num.CityDisabilityNum[i] = v + city_disability_num.CityDisabilityNum[i]
			}

			cityDisabilityNumByte, err := json.Marshal(city_disability_num)
			if err != nil {
				log.Logger.Error("地图数据城市残疾人数据统计 map json 序列化失败")
			}
			err = stub.PutState(common.CITY_DISABILITY_NUM, cityDisabilityNumByte)
			if err != nil {
				log.Logger.Error("地图数据城市残疾人数据统计 上链失败")
			}
		}
	}
	//return
}*/

// 统计对应城市康复机构数据
/*func cityRehabilitationNum(stub shim.ChaincodeStubInterface, param map[string]int) {
	fmt.Println("========================统计对应城市康复机构数据========================")
	countByts, err := stub.GetState(common.CITY_REHABILITATION_NUM)
	if err != nil {
		var city_rehabilitation_num module.CityRehabilitationNum
		city_rehabilitation_num.CityRehabilitationNum = make(map[string]int)
		for i, v := range param {
			city_rehabilitation_num.CityRehabilitationNum[i] = v
		}

		cityRehabilitationNumBytes, _ := json.Marshal(city_rehabilitation_num)
		fmt.Println(city_rehabilitation_num)
		_ = stub.PutState(common.CITY_REHABILITATION_NUM, cityRehabilitationNumBytes)
	} else {
		city_rehabilitation_num := module.CityRehabilitationNum{CityRehabilitationNum: make(map[string]int)}
		err = json.Unmarshal(countByts, &city_rehabilitation_num)
		if err != nil {
			var city_rehabilitation_num module.CityRehabilitationNum
			city_rehabilitation_num.CityRehabilitationNum = make(map[string]int)
			for i, v := range param {
				city_rehabilitation_num.CityRehabilitationNum[i] = v
			}

			cityDisabilityNumBytes, _ := json.Marshal(city_rehabilitation_num)
			fmt.Println(city_rehabilitation_num)
			_ = stub.PutState(common.CITY_REHABILITATION_NUM, cityDisabilityNumBytes)
		} else {

			for i, v := range param {
				city_rehabilitation_num.CityRehabilitationNum[i] = v + city_rehabilitation_num.CityRehabilitationNum[i]
			}

			cityDisabilityNumBytes, err := json.Marshal(city_rehabilitation_num)
			if err != nil {
				log.Logger.Error("地图数据城市残疾人数据统计 map json 序列化失败")
			}
			err = stub.PutState(common.CITY_REHABILITATION_NUM, cityDisabilityNumBytes)
			if err != nil {
				log.Logger.Error("地图数据城市残疾人数据统计 上链失败")
			}
		}
	}
	//return
}*/

// 统计对应城市康复救助补贴数据
/*func citySubsidyNum(stub shim.ChaincodeStubInterface, param map[string]int) {
	fmt.Println("========================统计对应城市康复救助补贴数据========================")

	countByts, err := stub.GetState(common.CITY_SUBSIDY_NUM)
	if err != nil {
		var city_subsidy_num module.CitySubsidyNum
		city_subsidy_num.CitySubsidyNum = make(map[string]int)
		for i, v := range param{
			city_subsidy_num.CitySubsidyNum[i] = v
		}

		citySubsidyNumBytes, _ := json.Marshal(city_subsidy_num)
		fmt.Println(city_subsidy_num)
		_ = stub.PutState(common.CITY_SUBSIDY_NUM, citySubsidyNumBytes)
	} else {
		city_subsidy_num := module.CitySubsidyNum{CitySubsidyNum: make(map[string]int)}
		err = json.Unmarshal(countByts, &city_subsidy_num)
		if err != nil {
			var city_subsidy_num module.CitySubsidyNum
			city_subsidy_num.CitySubsidyNum = make(map[string]int)
			for i, v := range param{
				city_subsidy_num.CitySubsidyNum[i] = v
			}

			citySubsidyNumBytes, _ := json.Marshal(city_subsidy_num)
			fmt.Println(city_subsidy_num)
			_ = stub.PutState(common.CITY_SUBSIDY_NUM, citySubsidyNumBytes)
		} else {
			for i, v := range param{
				city_subsidy_num.CitySubsidyNum[i] = v + city_subsidy_num.CitySubsidyNum[i]
			}

			citySubsidyNumBytes, err := json.Marshal(city_subsidy_num)
			if err != nil {
				log.Logger.Error("地图数据城市残疾人数据统计 map json 序列化失败")
			}
			err = stub.PutState(common.CITY_SUBSIDY_NUM, citySubsidyNumBytes)
			if err != nil {
				log.Logger.Error("地图数据城市残疾人数据统计 上链失败")
			}
		}
	}
	//return
}*/

/**
 * 记录残疾人交易数目
 */
/*func recordDisabilityTxNumber(stub shim.ChaincodeStubInterface, num int) {
	fmt.Println("========================统计残疾人交易数目========================")
	// 记录tx count number
	countByts, err := stub.GetState(common.TX_COUNT + common.ULINE + common.DISABILITY)
	if err != nil {
		var txCount module.DisabilityTxCount
		txCount.Count = uint64(num)
		txBytes, _ := json.Marshal(txCount)
		fmt.Println(txCount)
		_ = stub.PutState(common.TX_COUNT+common.ULINE+common.DISABILITY, txBytes)

	} else {
		txCount := module.DisabilityTxCount{Count: 0}
		err = json.Unmarshal(countByts, &txCount)
		if err != nil {
			var txInfo module.DisabilityTxCount
			txInfo.Count = uint64(num)
			txInfoBytes, _ := json.Marshal(txInfo)
			fmt.Println(txInfo)
			_ = stub.PutState(common.TX_COUNT+common.ULINE+common.DISABILITY, txInfoBytes)
		} else {
			txCount.Count = txCount.Count + uint64(num)
			txBytes, _ := json.Marshal(txCount)
			fmt.Println(txCount)
			_ = stub.PutState(common.TX_COUNT+common.ULINE+common.DISABILITY, txBytes)
		}
	}
	//return
}*/

/**
 * 记录康复机构交易数目
 */
/*func recordRehabilitationTxNumber(stub shim.ChaincodeStubInterface, num int) {
	fmt.Println("========================统计康复机构交易数目========================")
	// 记录tx count number
	countByts, err := stub.GetState(common.TX_COUNT + common.ULINE + common.REHABILITATION)
	if err != nil {
		var txCount module.RehabilitationTxCount
		txCount.Count = uint64(num)
		txBytes, _ := json.Marshal(txCount)
		fmt.Println(txCount)
		_ = stub.PutState(common.TX_COUNT+common.ULINE+common.REHABILITATION, txBytes)
	} else {
		txCount := module.RehabilitationTxCount{Count: 0}
		err = json.Unmarshal(countByts, &txCount)
		if err != nil {
			var txInfo module.RehabilitationTxCount
			txInfo.Count = uint64(num)
			txInfoBytes, _ := json.Marshal(txInfo)
			fmt.Println(txInfo)
			_ = stub.PutState(common.TX_COUNT+common.ULINE+common.REHABILITATION, txInfoBytes)
		} else {
			txCount.Count = txCount.Count + uint64(num)
			txBytes, _ := json.Marshal(txCount)
			fmt.Println(txCount)
			_ = stub.PutState(common.TX_COUNT+common.ULINE+common.REHABILITATION, txBytes)
		}
	}
	//return
}
*/
/**
 * 记录补贴申请交易数目
 */
/*func recordSubsidyTxNumber(stub shim.ChaincodeStubInterface, num int) {
	fmt.Println("========================统计补贴申请交易数目========================")
	// 记录tx count number
	countByts, err := stub.GetState(common.TX_COUNT + common.ULINE + common.SUBSIDY)
	if err != nil {
		var txCount module.SubsidyTxCount
		txCount.Count = uint64(num)
		txBytes, _ := json.Marshal(txCount)
		fmt.Println(txCount)
		_ = stub.PutState(common.TX_COUNT+common.ULINE+common.SUBSIDY, txBytes)
	} else {
		txCount := module.SubsidyTxCount{Count: 0}
		err = json.Unmarshal(countByts, &txCount)
		if err != nil {
			var txInfo module.SubsidyTxCount
			txInfo.Count = uint64(num)
			txInfoBytes, _ := json.Marshal(txInfo)
			fmt.Println(txInfo)
			_ = stub.PutState(common.TX_COUNT+common.ULINE+common.SUBSIDY, txInfoBytes)
		} else {
			txCount.Count = txCount.Count + uint64(num)
			txBytes, _ := json.Marshal(txCount)
			fmt.Println(txCount)
			_ = stub.PutState(common.TX_COUNT+common.ULINE+common.SUBSIDY, txBytes)
		}
	}
	//return
}*/